package com.javatip.common.utils.file;

import java.io.*;
import java.net.URLEncoder;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.servlet.http.HttpServletRequest;

/**
 * 文件处理工具类
 * 
 * @author ruoyi
 */
public class FileUtils
{
    public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+";

    /**
     * 输出指定文件的byte数组
     * 
     * @param filePath 文件路径
     * @param os 输出流
     * @return
     */
    public static void writeBytes(String filePath, OutputStream os) throws IOException
    {
        FileInputStream fis = null;
        try
        {
            File file = new File(filePath);
            if (!file.exists())
            {
                throw new FileNotFoundException(filePath);
            }
            fis = new FileInputStream(file);
            byte[] b = new byte[1024];
            int length;
            while ((length = fis.read(b)) > 0)
            {
                os.write(b, 0, length);
            }
        }
        catch (IOException e)
        {
            throw e;
        }
        finally
        {
            if (os != null)
            {
                try
                {
                    os.close();
                }
                catch (IOException e1)
                {
                    e1.printStackTrace();
                }
            }
            if (fis != null)
            {
                try
                {
                    fis.close();
                }
                catch (IOException e1)
                {
                    e1.printStackTrace();
                }
            }
        }
    }


    /**
     * 删除文件夹及其内容
     */
    public static boolean deleteFolderFile(String folderPath) {
        System.out.println("Delete folder: " + folderPath);
        File file = new File(folderPath);
        if (!file.exists()) {
            return false;
        }

        if (file.isDirectory()) {
            File[] files = file.listFiles();
            if (files != null) {
                for (File f : files) {
                    if (f.isDirectory()) {
                        // 递归删除子文件夹及其内容
                        deleteFolderFile(f.getAbsolutePath());
                    } else {
                        System.out.println("Delete file: " + f.getAbsolutePath());
                        f.delete(); // 删除文件
                    }
                }
            }
        }

        return file.delete(); // 删除文件夹本身
    }

    /**
     * 删除文件
     * 
     * @param filePath 文件
     * @return
     */
    public static boolean deleteFile(String filePath)
    {
        boolean flag = false;
        File file = new File(filePath);
        // 路径为文件且不为空则进行删除
        if (file.isFile() && file.exists())
        {
            file.delete();
            flag = true;
        }
        return flag;
    }

    /**
     * 文件名称验证
     * 
     * @param filename 文件名称
     * @return true 正常 false 非法
     */
    public static boolean isValidFilename(String filename)
    {
        return filename.matches(FILENAME_PATTERN);
    }

    /**
     * 下载文件名重新编码
     * 
     * @param request 请求对象
     * @param fileName 文件名
     * @return 编码后的文件名
     */
    public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException
    {
        final String agent = request.getHeader("USER-AGENT");
        String filename = fileName;
        if (agent.contains("MSIE"))
        {
            // IE浏览器
            filename = URLEncoder.encode(filename, "utf-8");
            filename = filename.replace("+", " ");
        }
        else if (agent.contains("Firefox"))
        {
            // 火狐浏览器
            filename = new String(fileName.getBytes(), "ISO8859-1");
        }
        else if (agent.contains("Chrome"))
        {
            // google浏览器
            filename = URLEncoder.encode(filename, "utf-8");
        }
        else
        {
            // 其它浏览器
            filename = URLEncoder.encode(filename, "utf-8");
        }
        return filename;
    }

    // 检测是否存在文件夹
    public static boolean isExist(String folderPath) {
        File folder = new File(folderPath);
        // 判断文件夹是否存在并且是一个目录
        return folder.exists() && folder.isDirectory();
    }

    public static void createFolder(String jsonOutputPath) {
        File file = new File(jsonOutputPath);
        if (!file.exists()) {
            file.mkdirs();
        }
    }

    // 压缩文件夹
    public static boolean compressFolder(String folderPath, String zipFilePath) {
        File folder = new File(folderPath);
        if (!folder.exists() || !folder.isDirectory()) {
            System.out.println("指定路径不是有效的文件夹");
            return false;
        }

        try (FileOutputStream fos = new FileOutputStream(zipFilePath);
             ZipOutputStream zos = new ZipOutputStream(fos)) {

            // 递归添加文件夹中的文件
            addFolderToZip(folder, folder.getName(), zos);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    // 递归添加文件夹中的文件
    private static void addFolderToZip(File folder, String parentFolderName, ZipOutputStream zos) throws IOException {
        // 获取文件夹中的所有文件和子文件夹
        File[] files = folder.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    // 如果是子文件夹，递归调用
                    addFolderToZip(file, parentFolderName + "/" + file.getName(), zos);
                } else {
                    // 如果是文件，直接添加
                    try (FileInputStream fis = new FileInputStream(file)) {
                        // 以相对路径添加文件
                        zos.putNextEntry(new ZipEntry(parentFolderName + "/" + file.getName()));
                        byte[] buffer = new byte[1024];
                        int length;
                        while ((length = fis.read(buffer)) > 0) {
                            zos.write(buffer, 0, length);
                        }
                        zos.closeEntry();
                    }
                }
            }
        }
    }
}
